﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Management;
using System.Management.Automation;
using Microsoft.Hpc.Scheduler;

namespace pshcli
{
    class HelperMethods
    {
        public HelperMethods()
        { }

        public string ReadXmlProp(string prop, string xmlfile)
        {
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.Load(xmlfile);
            XmlNode node = xmldoc.DocumentElement;

            return node.SelectSingleNode(prop).InnerText;
        }

        private string ReplaceEnvInPath(string path, string env)
        {
            //remove %% from env
            string envvar = System.Environment.GetEnvironmentVariable(env);
            if (envvar != null) envvar = envvar.Trim(); else envvar = "";

            if (!String.IsNullOrEmpty(envvar))
                if (path.Contains("%" + env + "%"))
                    path = path.Replace("%" + env + "%", envvar);
            return path;
        }



        public static void StartXperf(string fetl)
        {
            Process dproc = new Process();

            string profile = "";
            if (!String.IsNullOrEmpty(DwarfBench.gsettings.xperfcounterselect))
                profile = DwarfBench.gsettings.xperfcounterselect;
            else
                profile = "Base";

            DwarfBench.glog.WriteLog("START_XPERF", "Starting xperf with profiling setting: " + profile);

            dproc.StartInfo.FileName = "cmd.exe";
            dproc.StartInfo.Arguments = "/C xperf -on " + profile + " -f " + "\"" + fetl + "\"";
            dproc.StartInfo.UseShellExecute = false;
            dproc.StartInfo.CreateNoWindow = true;
            dproc.Start();

            while (!dproc.HasExited)
            {
                Thread.Sleep(700);
            }
        }

        public static void StopXperf()
        {
            Process dproc = new Process();

            DwarfBench.glog.WriteLog("START_XPERF", "Stopping xperf.");

            dproc.StartInfo.FileName = "cmd.exe";
            dproc.StartInfo.Arguments = "/C xperf -stop";
            dproc.StartInfo.UseShellExecute = false;
            dproc.StartInfo.CreateNoWindow = true;
            dproc.Start();

            while (!dproc.HasExited)
            {
                Thread.Sleep(700);
            }
        }

        public static void StartXperfView(string fetl)
        {
            Process dproc = new Process();
            dproc.StartInfo.FileName = "cmd.exe";
            dproc.StartInfo.Arguments = "/C xperfview -i " + fetl;
            dproc.StartInfo.UseShellExecute = false;
            dproc.StartInfo.CreateNoWindow = true;
            dproc.Start();
        }



        public static void DeleteFilesInDirectory(string dir, string ext)
        {
            string[] fileList = Directory.GetFiles(dir, ext);

            foreach (string file in fileList)
            {
                FileInfo delfile = new FileInfo(file);
                if (delfile.Exists)
                    delfile.Delete();
            }
        }

        public static bool DeleteFile(string file)
        {
            try
            {
                FileInfo delfile = new FileInfo(file);
                if (delfile.Exists)
                {
                    if (!IsFileInUse(file))
                        delfile.Delete();
                }
            }
            catch (Exception e)
            {
                //This should break the exception as tracing may fail
                Console.WriteLine("IO error: Can't delete file {0} because {1}.", file, e.ToString());
                return false;
            }
            return true;
        }

        public static bool IsFileReadable(string file, FileMode fmode, FileAccess faccess, FileShare fshare)
        {
            FileStream ft = null;

            try
            {
                ft = File.Open(file, fmode, faccess, fshare);
                ft.Close();
                ft.Dispose();
            }
            catch (Exception)
            {
                return false;
            }

            return true;


        }

        public static bool IsFileInUse(string file)
        {
            bool isUsed = false;
            FileStream ft = null;

            try
            {
                ft = File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
            }
            catch (System.IO.FileNotFoundException)
            {
                isUsed = false;
            }
            catch (IOException)
            {
                isUsed = true;
            }

            if (ft != null)
            {
                ft.Close();
                ft.Dispose();
                return isUsed;
            }
            return false;

        }

        public static void ExecCommand(string bin, string par, bool wait)
        {
            Process dproc = new Process();
            dproc.StartInfo.FileName = bin;
            dproc.StartInfo.Arguments = par;
            dproc.StartInfo.UseShellExecute = false;
            dproc.StartInfo.CreateNoWindow = true;

            DwarfBench.glog.WriteLog("EXECUTE_COMMAND", "FileName: " + dproc.StartInfo.FileName);
            DwarfBench.glog.WriteLog("EXECUTE_COMMAND", "Arguments: " + dproc.StartInfo.Arguments);

            dproc.Start();

            if (wait)
                while (!dproc.HasExited)
                    Thread.Sleep(500);
        }

        public static int GetTotalLocaLCoreCount()
        {
            int proccount = 0;

            ManagementObjectSearcher procquery = new ManagementObjectSearcher("SELECT * FROM Win32_Processor");
            ManagementObjectCollection procs = procquery.Get();
            foreach (ManagementObject proc in procs)
                proccount += Int32.Parse(proc["NumberOfCores"].ToString());

            return proccount;
        }

    }
}
